// 类型判断
export function isType(obj, type) {
    // tostring会返回对应不同的标签的构造函数
    const toString = Object.prototype.toString
    const map = {
        '[object Boolean]': 'boolean',
        '[object Number]': 'number',
        '[object String]': 'string',
        '[object Function]': 'function',
        '[object Array]': 'array',
        '[object Date]': 'date',
        '[object RegExp]': 'regExp',
        '[object Object]': 'object',
        '[object Undefined]': 'undefined',
        '[object Null]': 'null',
        '[object Error]': 'error',
    }
    if (obj instanceof HTMLElement) {
        return type ? type === 'element' : 'element'
    }
    return type ? type === map[toString.call(obj)] : map[toString.call(obj)]
}

// 合并对象
export function mergeObject(target, source) {
    for (const key in source) {
        if (target[key]) {
            for (const childKey in source[key]) {
                if (target[key][childKey] === undefined) {
                    target[key][childKey] = source[key][childKey];
                }
            }
        } else {
            target[key] = source[key];
        }
    }
    return target;
}
/**
 * deepCopy 深拷贝（对象/数组）
 * @param obj 要拷贝的数据(对象/数组)
 * @returns {Object/Array} 返回对象或数组
 */
export function deepCopy(obj, parent = null) {
    //parent用于递归循环引用爆栈处理
    // 创建一个新对象
    let result = new obj.constructor() //保持继承链
    let keys = Object.keys(obj),
        key = null,
        temp = null,
        _parent = parent
    // 该字段若有父级则需要追溯该字段的父级
    while (_parent) {
        // 如果该字段引用了它的父级则为循环引用
        if (_parent.originalParent === obj) {
            return _parent.currentParent // 循环引用直接返回同级的新对象
        }
        _parent = _parent.parent
    }
    for (let i = 0; i < keys.length; i++) {
        key = keys[i]
        temp = obj[key]
        if (temp && isType(temp) === 'date') {
            result[key] = new Date(temp)
            continue
        }
        if (temp && isType(temp) === 'regExp') {
            result[key] = new RegExp(temp)
            continue
        }
        // 若字段的值是一个对象/数组
        if (temp && (isType(temp) === 'object' || isType(temp) === 'array')) {
            // 递归执行深拷贝 将同级的待拷贝对象与新对象传递给 parent 方便追溯循环引用
            result[key] = deepCopy(temp, {
                originalParent: obj,
                currentParent: result,
                parent: parent
            })
        } else {
            result[key] = temp
        }
    }
    return result
}

// 函数节流
export function throttle(fn, wait = 300) {
    var timer;
    return function (...args) {
        if (!timer) {
            timer = setTimeout(() => timer = null, wait);
            return fn.apply(this, args);
        }
    }
}

// 函数防抖
export function debounce(fn, delay){
	var timer = null;
	return function(...args){
    	clearTimeout(timer);
    	timer = setTimeout(() => fn.apply(this, args), delay);
	}
}


// 获取滚动条宽度
export const getScrollbarWidth = (() => {
    let scrollBarWidth;
    return function () {
        if (scrollBarWidth !== undefined) return scrollBarWidth;
        const outer = document.createElement('div');
        outer.className = 'el-scrollbar__wrap';
        outer.style.overflow = 'scroll';
        outer.style.visibility = 'hidden';
        outer.style.width = '100px';
        outer.style.height = '100%';
        outer.style.position = 'absolute';
        outer.style.top = '-9999px';
        document.body.appendChild(outer);

        const widthNoScroll = outer.offsetWidth;
        outer.style.overflow = 'scroll';

        const inner = document.createElement('div');
        inner.style.width = '100%';
        outer.appendChild(inner);

        const widthWithScroll = inner.offsetWidth;
        outer.parentNode.removeChild(outer);
        scrollBarWidth = widthNoScroll - widthWithScroll;

        return scrollBarWidth;
    }
})();

// 获取键盘方向
export function getKeyboardDir(event) {
    var code;
    if (event.key !== undefined) {
        code = event.key;
    } else if (event.keyCode !== undefined) {
        code = event.keyCode;
    }
    if (code == 'ArrowUp' || code == 38) code = 'top';
    if (code == 'ArrowDown' || code == 40) code = 'bottom';
    if (code == 'Enter' || code == 13) code = 'ok';
    return code;
}

// // 获取当前元素所有计算后的样式
// export function getStyleComputedProperty(element, property) {
//     var css = window.getComputedStyle(element, null);
//     return css[property];
// }

// // 是否为滚动元素
// export function isScrollElement(element) {  
//     return ['scroll', 'auto'].indexOf(getStyleComputedProperty(element, 'overflow')) !== -1 ||
//     ['scroll', 'auto'].indexOf(getStyleComputedProperty(element, 'overflow-x')) !== -1 ||
//     ['scroll', 'auto'].indexOf(getStyleComputedProperty(element, 'overflow-y')) !== -1
// }

// // 获取滚动容器
// export function getScrollElement(element) {
//     return isScrollElement(element) ? element : element.parentNode;
// }